package com.smart.thrift.discoveryandbalance.balancer;

import com.smart.thrift.config.client.ThriftClientManager;
import com.smart.thrift.constants.ThriftConstants;
import com.smart.thrift.discoveryandbalance.discovery.Registry;
import com.smart.thrift.discoveryandbalance.discovery.ThriftServerNode;
import com.smart.thrift.discoveryandbalance.discovery.consul.ConsulRegistry;
import com.smart.thrift.discoveryandbalance.discovery.consul.ThriftConsulServerNodeList;
import com.smart.thrift.discoveryandbalance.discovery.zookeeper.ThriftZookeeperServerNodeList;
import com.smart.thrift.discoveryandbalance.discovery.zookeeper.ZookeeperRegistry;
import com.smart.thrift.discoveryandbalance.rule.IRule;
import com.smart.thrift.model.pool.TransportKeyedObjectPool;
import lombok.Getter;
import lombok.Setter;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public abstract class AbstractServerListLoadBalancer implements ILoadBalancer<ThriftServerNode> {

    @Getter
    @Setter
    protected TransportKeyedObjectPool transportKeyedObjectPool;

    public static AbstractServerListLoadBalancer getServerListLoadBalancer(IRule rule) {
        ThriftClientManager manager = ThriftClientManager.getInstance();
        Registry<?> registry = manager.getRegistry();
        //目前只提供RoundRobinRule，可以拓展discoveryandbalance.rule
        //ThriftClientProperties properties = manager.getProperties();
        //switch (properties.getDiscovery().getBalanceRule()){
        //    case "Robin":
        //}
        AbstractServerListLoadBalancer abstractServerListLoadBalancer = null;
        if (ThriftConstants.DiscoveryType.CONSUL.equals(registry.getClientType())){
            ThriftConsulServerNodeList serverNodeList = ThriftConsulServerNodeList.singleton((ConsulRegistry) registry);
            abstractServerListLoadBalancer = new ThriftConsulServerListLoadBalancer(serverNodeList, rule);
        }else if (ThriftConstants.DiscoveryType.ZOOKEEPER.equals(registry.getClientType())){
            ThriftZookeeperServerNodeList serverNodeList = ThriftZookeeperServerNodeList.singleton((ZookeeperRegistry) registry);
            abstractServerListLoadBalancer = new ThriftZookeeperServerListLoadBalancer(serverNodeList, rule);
        }
        if (Objects.nonNull(abstractServerListLoadBalancer)) {
            abstractServerListLoadBalancer.setTransportKeyedObjectPool(manager.getObjectPool());
        }
        return abstractServerListLoadBalancer;
    }

    @Override
    public boolean containsServerNode(String key) {
        return getAllServerNodes().containsKey(key);
    }

    @Override
    public Map<String, LinkedHashSet<ThriftServerNode>> getAllServerNodes() {
        return getThriftServerNodeList().getServerNodeMap();
    }

    @Override
    public Map<String, LinkedHashSet<ThriftServerNode>> getRefreshedServerNodes() {
        return getThriftServerNodeList().refreshThriftServers();
    }

    @Override
    public List<ThriftServerNode> getServerNodes(String key) {
        return getThriftServerNodeList().getThriftServer(key);
    }

    @Override
    public List<ThriftServerNode> getRefreshedServerNodes(String key) {
        return getThriftServerNodeList().refreshThriftServer(key);
    }

}
